package org.examples;

import java.io.IOException;
import java.nio.CharBuffer;
import java.util.concurrent.Future;

import org.apache.hc.client5.http.async.methods.AbstractCharResponseConsumer;
import org.apache.hc.client5.http.async.methods.SimpleHttpRequest;
import org.apache.hc.client5.http.async.methods.SimpleRequestBuilder;
import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient;
import org.apache.hc.client5.http.impl.async.HttpAsyncClients;
import org.apache.hc.core5.http.ContentType;
import org.apache.hc.core5.http.HttpException;
import org.apache.hc.core5.http.HttpHost;
import org.apache.hc.core5.http.HttpResponse;
import org.apache.hc.core5.http.message.StatusLine;
import org.apache.hc.core5.http.nio.entity.BasicAsyncEntityProducer;
import org.apache.hc.core5.http.nio.support.BasicRequestProducer;
import org.apache.hc.core5.io.CloseMode;

public class AsyncBodyIssue {
  public static void main(final String[] args) throws Exception {
    CloseableHttpAsyncClient client = HttpAsyncClients.custom()
//        .setMaxConnTotal(100)
//        .setMaxConnPerRoute(100)
        .build();
//    final CloseableHttpAsyncClient client = HttpAsyncClients.createDefault();
    client.start();
    final HttpHost target = new HttpHost("httpbin.org");
    String bodyString = "{\"k\":\"v\"}";
    final SimpleHttpRequest request = SimpleRequestBuilder
        .post()
        .setHttpHost(target)
        .setPath("/post")
        .setBody(bodyString, ContentType.APPLICATION_JSON)
        .build();
    BasicAsyncEntityProducer basicAsyncEntityProducer = new BasicAsyncEntityProducer(
        bodyString,
        ContentType.APPLICATION_JSON
    );
//    AudioAsyncResponseConsumer.recreateAudioFile();
    final Future<Void> future = client.execute(
        new BasicRequestProducer(request, basicAsyncEntityProducer),
        new AbstractCharResponseConsumer<Void>() {
          @Override
          protected void start(
              final HttpResponse response,
              final ContentType contentType) throws HttpException, IOException {
            System.out.println(request + "->" + new StatusLine(response));
          }

          @Override
          protected int capacityIncrement() {
            return Integer.MAX_VALUE;
          }

          @Override
          protected void data(final CharBuffer data, final boolean endOfStream) throws IOException {
            while (data.hasRemaining()) {
              System.out.print(data.get());
            }
            if (endOfStream) {
              System.out.println();
            }
          }

          @Override
          protected Void buildResult() throws IOException {
            return null;
          }

          @Override
          public void failed(final Exception cause) {
            System.out.println(request + "->" + cause);
          }

          @Override
          public void releaseResources() {
          }

        }, null);
    future.get();
    System.out.println("Shutting down");
    client.close(CloseMode.GRACEFUL);
  }
}
